package jp.co.redfox.archclub.poker;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import jp.co.redfox.archclub.poker.Question.Type;
import jp.co.redfox.archclub.poker.player.ComPlayer;
import jp.co.redfox.archclub.poker.player.NoMoneyException;
import jp.co.redfox.archclub.poker.player.UserPlayer;
import jp.co.redfox.archclub.poker.player.YunchoruPlayer;
import jp.co.redfox.archclub.utility.datas.FileUtil;
import jp.co.redfox.archclub.utility.datas.UserPlayerData;

public class Game {
    private static ThreadLocal<Game> currentGame = new ThreadLocal<>();
    private List<Player> players;
    private Deck deck = new Deck();
    private boolean continueFlg = true;

    public static void main(String[] args) {
        Game game = new Game();
        game.start();
    }

    private void showLogo() {
        System.out.println(FileUtil.load("opening.dat"));
    }

    public static Game getCurrentGame() {
        return currentGame.get();
    }

    public Deck getDeck() {
        return deck;
    }

    /**
     * ゲーム続行確認
     * 
     * @return true ゲーム続行　false ゲーム終了
     */
    private void repeat() {
        YesNoQuery query = new YesNoQuery();
        YesNoListener gameContinueListener = new ContinueYesNoListener(getCurrentGame());
        query.addListener(gameContinueListener);
        query.ask("Repeat game? ");
    }

    /**
     * ゲームを開始
     */
    public void start() {
        currentGame.set(this);
        showLogo();
        do {
            init();
            play();
            repeat();
        } while (continueFlg);
        end();
    }

    private void init() {
        System.out.println("Start game.");
        // 順番を決める
        decideTurn();

        // shuffule cards
        for (Player player : players)
            player.dropAll();

        deck.initialize();

        // カードを配る
        deal();
    }

    /**
     * ゲームをする
     */
    public void play() {
        System.out.println("Start match.");
        // 参加料をとる
        ante();

        // カードを交換する
        changeCard();

        // 勝負する？
        if ( ! confirmGame())
            return;

        // コイン
        bet();

        // 勝負の判定をする
        judgeGame();

    }

    private void bet() {

    }

    private boolean confirmGame() {
        Question question = new Question(Type.selectable, "bet or fold? ", "y/n", new String[] { "y", "n" });
        String answer = question.ask();
        return "y".equals(answer);
    }

    /**
     * 参加料を徴収
     */
    private void ante() {
        for (Player player : players)
            try {
                player.payAnte();
            } catch (NoMoneyException e) {
                throw new GameException("Get out here!", e);
            }
    }

    /**
     * プレーヤー全員にカードを配る
     */
    private void deal() {
        for (Player player : players)
            try {
                player.draw(5);
            } catch (HandOverFlowException e) {
                throw new GameException("You are cheat player!", e);
            }
    }

    /**
     * 順番設定
     */
    private void decideTurn() {
        players = new ArrayList<>();
        System.out.println("Input your name.");
        Scanner nameScanner = new Scanner(System.in);
        String name = nameScanner.nextLine();

        UserPlayer user = UserPlayerData.getInstance().load(name);
        if (user == null)
            user = new UserPlayer((name == null || name.isEmpty()) ? "☆Chage☆" : name);
        UserPlayerData.save(user);

        System.out.println("Your name is " + user.getName());
        Question question = new Question(Type.selectable, "decide your dealling order. ", "1 or 2", new String[] { "1",
                "2" });
        String order = question.ask();
        switch (order) {
        case "1": {
            players.add(user);
            players.add(new YunchoruPlayer());
            break;
        }
        case "2": {
            players.add(new YunchoruPlayer());
            players.add(user);
            break;
        }
        default: {
            players.add(new YunchoruPlayer());
            players.add(user);
            break;
        }
        }
    }

    /**
     * ゲームを終了
     */
    public void end() {
        System.out.println("End game.");
        // 勝率を出す

        // エンドロール
        System.out.println(FileUtil.load("ending.dat"));
    }

    /**
     * TODO
     */
    private void judgeGame() {
         // カードの役の判定する
//         Player winner = judgeWinner();
//         if(winner == you)
//         System.out.println("you win!");
//         else
//         System.out.println("you lose");
    }

    private void changeCard() {
        for (Player player : players)
            try {
                player.changeCards();
            } catch (HandOverFlowException e) {
                throw new GameException("You are cheat player!", e);
            }
    }

    public void setContinueFlg(boolean continueFlg) {
        this.continueFlg = continueFlg;
    }

}
